<template>
  <div class="e-automate w-full relative" v-loading="loading">
    <div class="e-automate-connected e-automate--block flex overflow-hidden">
      <div
        class="e-automate-connected__left flex flex-1 flex-col justify-between"
      >
        <span>Connected</span>
        <ZTooltip :line="1" placement="right" :content="server">
          <span>Server: {{ server }}</span>
        </ZTooltip>
        <ZTooltip
          :line="1"
          placement="top"
          wrap="anywhere"
          toolTipType="e-automate"
          :content="agent.secret"
        >
          <span>Secret: {{ agent.secret }}</span>
        </ZTooltip>
      </div>
      <div class="e-automate-connected__action flex items-center">
        <a :href="appPackage" style="text-decoration: none" target="_blank">
          <ZIcon
            :content="$t('custom.connector.sqldownloadUrl')"
            icon="el-icon-download"
            hover
            style="margin-right: 16px"
            tooltip
          />
        </a>

        <ZIcon icon="cuifont icon_notepad" hover @click="openLog({})" />
      </div>
    </div>

    <div class="e-automate-connector">
      <el-button size="mini" @click="onCreateDB" icon="cuifont icon_add" v-if="!hideBtn">
        Add Connector
      </el-button>
    </div>

    <div class="e-automate-db">
      <div
        class="e-automate-db-item e-automate--block flex flex-col overflow-hidden"
        v-for="(item, index) in agent.sqlAgentIntegrations"
        :key="index"
        v-loading="item._loading"
      >
        <div
          class="e-automate-db-item__header flex cursor-pointer"
          @click.stop="toggleDBForm(item)"
        >
          <div class="e-automate-db-item__header__left flex flex-col flex-1">
            <div
              class="e-automate-db-item__header__left-title flex items-center"
            >
              <span>{{
                $t(`custom.connector.sqlagent.dbType${item.databaseType}`)
              }}</span>

              <div
                class="e-automate-db-item__header__left-title--tag"
                style="margin-left: 16px"
                v-if="item._status"
              >
                <el-tag :type="item._status" size="mini" effect="dark">
                  {{ item._message }}
                </el-tag>
              </div>
            </div>
            <div
              class="e-automate-db-item__header__left-bottom"
              v-if="item.datasets && item.datasets.length"
            >
              <div
                class="dataset-item flex items-center"
                v-for="(d, i) in item.datasets"
                :key="i"
              >
                <div class="dataset-item-block inline-flex items-center flex-1">
                  <span class="dataset-item-block-name">DB Type: </span>
                  <span class="dataset-item-block-value">
                    {{
                      $t(`custom.connector.sqlagent.dbType${item.databaseType}`)
                    }}
                  </span>
                </div>
                <div class="dataset-item-block inline-flex items-center flex-1">
                  <span class="dataset-item-block-name">DB Server: </span>
                  <span class="dataset-item-block-value"> {{ item.ip }} </span>
                </div>
                <div class="dataset-item-block inline-flex items-center flex-1" style="padding-right: 10px">
                  <span class="dataset-item-block-name">Dataset: </span>
                    <ZTooltip :content="d.name"
                     :line="1"
                     :toolTipType="'e-automate'"
                     placement="top">
                     <router-link
                      class="dataset-item-block-link"
                      :to="`dataset-${d.id}?pageid=${d.id}&name=${d.name}`">
                       {{ d.name }}
                     </router-link>
                   </ZTooltip> 
                
                </div>
                <div class="dataset-item-block inline-flex items-center flex-1">
                  <span class="dataset-item-block-name">User Name: </span>
                  <span class="dataset-item-block-value">
                    {{ item.userId }}</span
                  >
                </div>
              </div>

              <div
                class="sql-agent-db-item__header__left-bottom-lastsync"
                v-if="item.lastRecordTime"
              >
                Last Sync: {{ item.lastRecordTime }}
              </div>
            </div>
          </div>
          <div class="e-automate-db-item__header__right flex items-center">
            <ZIcon
              icon="cuifont icon_edit"
              style="margin-right: 16px"
              @click.stop.native="toggleDBForm(item)"
              hover
            />
            <ZIcon
              icon="cuifont icon_notepad"
              style="margin-right: 16px"
              @click.stop.native="openLog(item)"
              hover
            />
            <ZIcon
              icon="cuifont icon_delete"
              @click.stop.native="onDeleteDB(item, index)"
              hover
            />
          </div>
        </div>

        <div
          class="e-automate-db-item__content overflow-hidden"
          :style="{
            height: item._db_show ? '' : 0,
            borderTop: item._db_show ? '1px solid rgba(0, 0, 0, 0.08)' : 'none'
          }"
        >
          <el-form :model="item" :ref="`dbForm${index}`" :rules="rules">
            <el-row :gutter="24">
              <el-col :span="12">
                <el-form-item
                  :label="$t('custom.connector.sqlagent.dbType')"
                  prop="databaseType"
                >
                  <el-select v-model="item.databaseType" style="width: 100%">
                    <el-option
                      value="1"
                      :label="$t('custom.connector.sqlagent.dbType1')"
                    ></el-option>
                    <el-option
                      value="2"
                      :label="$t('custom.connector.sqlagent.dbType2')"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="Agent：" prop="agentId">
                  <el-select v-model="item.agentId" style="width: 100%">
                    <el-option
                      v-for="i in machines"
                      :key="i.agentId"
                      :label="i.name"
                      :value="i.agentId"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item
                  :label="$t('custom.connector.sqlagent.ip')"
                  prop="ip"
                >
                  <el-input
                    v-model="item.ip"
                    :placeholder="
                      item.databaseType === '1'
                        ? 'ip OR ip\\path,port'
                        : 'ip OR ip;port=xxxx'
                    "
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item
                  :label="$t('custom.connector.sqlagent.databaseName')"
                  prop="databaseName"
                >
                  <el-input
                    v-model="item.databaseName"
                    :placeholder="
                      $t('custom.connector.sqlagent.interdatabaseName')
                    "
                  ></el-input>
                </el-form-item>
              </el-col>
                <el-col :span="6">
                <el-form-item
                  :label="$t('custom.connector.sqlagent.databaseTimeZone')"
                  prop="timezoneId"
                >
                 <el-select v-model="item.timezoneId"
                      style="width:100%;"
                     :filterable="true"
                     :default-first-option="true"
                     :placeholder="$t('custom.connector.sqlagent.interdatabaseTimeZone')">
                        <el-option v-for="item in timezoneListData"
                                   :key="item"
                                   :label="item"
                                   :value="item">
                        </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item
                  :label="$t('custom.connector.sqlagent.userId')"
                  prop="userId"
                >
                  <el-input
                    v-model="item.userId"
                    :placeholder="$t('custom.connector.sqlagent.interuserId')"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item
                  :label="$t('custom.connector.sqlagent.password')"
                  prop="password"
                >
                  <el-input
                    v-model="item.password"
                    show-password
                    :placeholder="$t('custom.connector.sqlagent.interpassword')"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item>
                  <el-button
                    type="primary"
                    @click.stop="onSaveDB(item, index)"
                    size="mini"
                    >{{ $t('custom.connector.savequickbookspath') }}</el-button
                  >
                  <el-button
                    type="danger"
                    @click.stop="onDeleteDB(item, index)"
                    size="mini"
                    >Delete</el-button
                  >
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </div>
      </div>
    </div>

    <el-drawer
      style="
        position: fixed;
        min-width: 1324px;
        width: 75%;
        height: 100%;
        top: 0;
        right: 0;
        z-index: 2013;
      "
      :visible.sync="logVisible"
      :direction="'rtl'"
      append-to-body
      :custom-class="'connentor_drawer log-drawer'"
      :title="
        currentDB.databaseName
          ? `${currentDB.databaseName} - Connect Log`
          : `Connect Log`
      "
      type="primary"
    >
      <el-table
        :data="tableData"
        ref="table"
        header-cell-class-name="log_history_headers"
        v-loading="logloading"
      >
        <el-table-column
          prop="typeName"
          label="Connect Type"
          header-align="center"
          align="center"
        >
          <template slot-scope="scope">{{ scope.row.typeName }}</template>
        </el-table-column>
        <el-table-column
          prop="recordTime"
          label="Record Time"
          header-align="center"
          align="center"
        >
          <template slot-scope="scope">{{
            timeAreaFormat(scope.row.recordTime)
          }}</template>
        </el-table-column>

        <el-table-column
          prop="message"
          label="Message"
          header-align="center"
          align="center"
        >
          <template slot-scope="scope">
            {{ scope.row.message }}
          </template>
        </el-table-column>
        <el-table-column
          prop="detail"
          label="Detail"
          header-align="center"
          align="center"
        >
          <template slot-scope="scope"> {{ scope.row.error }}</template>
        </el-table-column>
      </el-table>
      <div class="flex justify-end" style="padding: 15px 0">
        <el-pagination
          :page-sizes="[10, 20, 50, 100]"
          :current-page="logParams.page"
          :page-size="logParams.pageSize"
          :total="Number(total)"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="sizeChange"
          @current-change="currentChange"
        >
        </el-pagination>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { Component } from './modules/Component.js'
import Trail from '@/components/storybook/mixins/trail'
import moment from 'moment'
import {
  fetchMachines,
  testConnect,
  fetchSqlResult,
  fetchDatasets
} from '@/api/new'
import { isNumber, cloneDeep, get, omit } from 'lodash'
import useDict from '@/components/storybook/hooks/useDict'
import useReconnection from '@/components/storybook/hooks/useReconnection'
import useErrorMessage from '@/components/storybook/hooks/useErrorMessage'
import ZIcon from '@/components/storybook/z-icon'
import ZTooltip from '@/components/storybook/z-tooltip'
import { TimeZoneNameList } from '@/utils'

export default {
  mixins: [Trail],
  name: 'EAutomateConfig',
  props: {
    form: {
      type: Object,
      default: () => ({})
    },
    collapse: Boolean,
    itemInfo: {
      type: Object,
      default: () => ({})
    },
  },
  components: {
    ZIcon,
    ZTooltip
  },
  data() {
    return {
      logVisible: false,
      currentDB: {},
      tableData: [],
      height: '200px',
      logParams: {
        page: 1,
        pageSize: 20,
        integrationId: null
      },
      logloading: false,
      total: 0,

      timer: null,

      loading: false,
      machines: [],
      agent: {
        sqlAgentIntegrations: []
      },
      rules: {
        databaseType: [
          {
            required: true,
            message: this.$t('validate.required'),
            trigger: 'blur'
          }
        ],
        agentId: [
          {
            required: true,
            message: this.$t('validate.required'),
            trigger: 'blur'
          }
        ],
        ip: [
          {
            required: true,
            message: this.$t('validate.required'),
            trigger: 'blur'
          }
        ],
        userId: [
          {
            required: true,
            message: this.$t('validate.required'),
            trigger: 'blur'
          }
        ],
        databaseName: [
          {
            required: true,
            message: this.$t('validate.required'),
            trigger: 'blur'
          }
        ],
          timezoneId: [
          {
            required: true,
            message: this.$t('validate.required'),
            trigger: 'blur'
          }
        ],
        password: [
          {
            required: true,
            message: this.$t('validate.required'),
            trigger: 'blur'
          }
        ]
      },
      timezoneListData:TimeZoneNameList()
    }
  },
  computed: {
    hideBtn () {
      return this.itemInfo.name.includes('On-Premise') && this.agent.sqlAgentIntegrations.length >= 1
    },
    appPackage() {
      return useDict('SQL AgentDownload URL', 'dictLabel', 'other_download_url').dictValue
    },
    server() {
      return `${window.location.origin}/`
    },
    sqlAgentdbArr(){
      return this.agent.sqlAgentIntegrations.filter(item=>item.datasets && item.datasets.length)
    }
  },
  watch: {
    collapse(val) {
      if (val) {
        this.init()
      }
    }
  },
  methods: {
    async init() {
      try {
        this.loading = true
        const [machines] = await Promise.all([this.getMachines()])
        this.machines = machines
        this.agent = cloneDeep(this.form)

        this.batchConnect()
      } catch (error) {
      } finally {
        this.loading = false
      }
    },
    async getMachines() {
      const { data: response } = await fetchMachines()
      if (response.code !== 0) {
        return []
      }

      return response.data || []
    },
    async batchConnect() {
      const { sqlAgentIntegrations } = this.agent || {}

      sqlAgentIntegrations.forEach(async i => {
        this.$set(i, '_connect', true)
        this.$set(i, '_loading', true)

        this.getConnect(i)
          .then(result => {
            this.$set(i, '_status', get(result, 'status'))
            this.$set(i, '_message', get(result, 'message'))
          })
          .catch(result => {
            if (result.message) {
              this.$set(i, '_status', 'danger')
              this.$set(i, '_message', get(result, 'message'))
            }
          })
          .finally(() => {
            this.$set(i, '_loading', false)
          })
      })
    },
    async getConnect(item, quantity = 10) {
      const {
        ip,
        userId,
        password,
        databaseName,
        timezoneId,
        databaseType,
        integrationId,
        agentId
      } = item
      const params = {
        ip,
        userId,
        password,
        databaseName,
        timezoneId,
        databaseType,
        agentId
      }

      const { data: resConnect } = await testConnect(params)
      if (resConnect.code !== 0) {
        return Promise.reject({
          status: 'danger',
          message: resConnect.msg
        })
      }

      const callback = result => {
        return (
          get(result, 'status') === 200 &&
          isNumber(get(result, 'data.data.code'))
        )
      }

      const resolve = result => {
        return Promise.resolve({
          status: get(result, 'data.data.code') === 0 ? 'success' : 'danger',
          message: get(result, 'data.data.message')
        })
      }
      const reject = (result, conf) => {
        let message = get(result, 'data.data.message')
        if (conf.retry <= 0) {
          message =
            'Your database server connection error, please try again later.'
        }
        return Promise.reject({
          status: 'danger',
          message
        })
      }

      const result = await useReconnection(fetchSqlResult, {
        callback,
        resolve,
        reject,
        quantity
      })({ requestId: resConnect.data })

      if (integrationId) {
        const { data: resDatasets } = await fetchDatasets({
          integrationId: item.integrationId
        })
        if (resDatasets.code === 0) {
          const datasets = (resDatasets.data || []).filter(i => i && i.id)
          this.$set(item, 'datasets', datasets)
        }
      }

      return result
    },

    async onDeleteDB(item, index) {
      const { integrationId, _connect } = item

      if (!_connect) {
        this.agent.sqlAgentIntegrations.splice(index, 1)
        return
      }

      this.$msgbox({
        title: 'Warning',
        message: this.$t('prompt.para', {
          handle: 'Do you want to disconnect this integration?'
        }),
        showCancelButton: true,
        confirmButtonText: this.$t('confirm'),
        cancelButtonText: this.$t('cancel'),
        type: 'warning',
        beforeClose: async (action, instance, done) => {
          if (action === 'confirm') {
            try {
              instance.confirmButtonLoading = true
              const params = {
                subjectCode: 'KVSAONPREMISE',
                integrationId
              }
              const { data: response } =
                await this.$interface.taskManager.delConnectorKeyApi(params)
              if (response.code !== 0) {
                throw response.msg
              }
              this.agent.sqlAgentIntegrations.splice(index, 1)
              this.form.sqlAgentIntegrations.splice(index, 1)
              this.$message.success(response.msg)
            } catch (error) {
              useErrorMessage(error)
            } finally {
              instance.confirmButtonLoading = false
            }
          }
          done()
        }
      })
    },
    async onSaveDB(item, index) {
      try {
        this.$set(item, '_loading', true)

        await this.$refs[`dbForm${index}`][0].validate()

        const result = await this.getConnect(item, 30)

        if (result.status === 'danger') {
          throw result
        }

        const { data: resPost } =
          await this.$interface.taskManager.postClientData({
            ...omit(item, ['_loading', '_db_show']),
            tenantId: this.$store.state.user.tenantCode,
            subjectCode: 'KVSAONPREMISE'
          })

        if (resPost.code !== 0) {
          throw {
            status: 'danger',
            message: resPost.msg
          }
        }

        this.$set(item, '_status', get(result, 'status'))
        this.$set(item, '_message', get(result, 'message'))
        if (!item._connect) {
          this.$set(item, '_connect', true)
          this.form.sqlAgentIntegrations.push(item)
        }

        this.$interface.taskManager.syncClientData({
          tenantId: this.$store.state.user.tenantCode,
          subjectCode: 'KVSAONPREMISE'
        })
        Component.$emit('getConnectorConfig')

        this.$message.success(get(result, 'message'))
      } catch (error) {
        if (error.message) {
          this.$set(item, '_status', 'danger')
          this.$set(item, '_message', get(error, 'message'))
          this.$message.error(get(error, 'message'))
        }
      } finally {
        this.$set(item, '_loading', false)
      }
    },

    onCreateDB() {
      this.agent.sqlAgentIntegrations.push({
        userId: null,
        databaseName: null,
        timezoneId: `${this.$store.state.user.timezoneId}`,
        integrationId: null,
        ip: null,
        password: null,
        tenantCode: this.$store.state.user.tenantCode,
        databaseType: '1',
        _db_show: true,
        _loading: false,
        datasets: [],
        agentId: this.machines.length ? this.machines[0].agentId : null
      })
    },

    toggleDBForm(item) {
      this.$set(item, '_db_show', !item._db_show)
    },

    copyPass(val) {
      const url = val
      const oInput = document.createElement('input')
      oInput.value = url
      document.body.appendChild(oInput)
      oInput.select()
      document.execCommand('Copy')
      oInput.remove()

      this.$message.success('Copied')
    },
    timeAreaFormat(time) {
      if (time) {
        return (
          moment
            .tz(time, this.$store.state.user.timezoneId)
            .format('MM/DD/YYYY HH:mm') +
          ' ' +
          moment.tz(time, this.$store.state.user.timezoneId).format('zz')
        )
      } else {
        return time
      }
    },
    openDetail() {
      this.$parent.showDetail(this.$parent.itemInfo)
    },
    handleChangeItem(item) {
      this.$set(item, 'showContext', !item.showContext)
    },
    openLog(item) {
      this.currentDB = item
      this.logVisible = true
      this.logParams.page = 1
      this.logParams.integrationId = this.currentDB.integrationId
      this.logParams.subjectCode = 'KVSAONPREMISE'
      if (!this.logParams.integrationId) this.logParams.integrationId = null
      this.getLog()
    },

    async getLog() {
      this.logloading = true
      if (this.sqlAgentdbArr.length>0) {
        const { data: res } = await this.$interface.taskManager.getLog(
        this.logParams
      )
      this.tableData = res.records 
      this.total = res.total
      } else {
        this.tableData = []
        this.total = 0
      }
     
      this.logloading = false
    },

    sizeChange(limit) {
      this.logParams.pageSize = limit
      this.logParams.page = 1
      this.getLog()
    },
    currentChange(current) {
      this.logParams.page = current
      this.getLog()
    }
  }
}
</script>

<style lang="scss" scoped>
.e-automate {
  padding: 10px 0 10px 80px;
  &-connected {
    &__left {
      font-size: 16px;
      span:nth-child(1) {
        font-weight: bold;
        color: rgba(0, 0, 0, 0.9);
      }
    }
  }
  &-connector {
    padding: 12px 0;
  }
  &--block {
    padding: 8px;
    background: rgba(246, 246, 246, 0.5);
    border-radius: 4px;
    border: 1px solid rgba(0, 0, 0, 0.06);
  }

  &-db {
    &-item {
      margin-bottom: 16px;
      &:last-of-type {
        margin-bottom: 0 !important;
      }
      &__header {
        &__left {
          &-title {
            font-size: 16px;
            font-weight: bold;
            color: rgba(0, 0, 0, 0.9);
          }
          &-bottom {
            padding: 5px 0;
            &__left {
              padding-right: 16px;
            }
          }
        }
      }

      &__content {
        transition: height 200ms;
      }
    }
  }
}
.dataset-item {
  height: 20px;
  line-height: 20px;
  &-block {
    &-name {
      font-size: 14px;
      color: #303133;
      font-weight: 500;
      padding-right: 8px;
    }
    &-value {
      font-size: 12px;
      color: #909399;
    }
    &-link {
      color: #409eff;
    }
  }
}
</style>
<style lang="scss" scoped>
::v-deep .el-drawer {
  width: 800px !important;
}
::v-deep #el-drawer__title {
  font-weight: 600 !important;
}
::v-deep .el-drawer__header {
  font-size: 18px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.75);
  padding: 15px;
  height: 54px;
  box-shadow: 0px 1px 0px 0px #f0f0f0;
  margin-bottom: 0;
}
::v-deep .el-drawer__body {
  padding: 20px;
  box-sizing: border-box;
  .el-header {
    padding: 0;
  }
  .el-table {
    width: 100%;
    height: calc(100% - 50px);
    border: 1px solid #ebeef5;
    border-bottom: 0;
    .el-table__body-wrapper {
      height: calc(100vh - 200px);
      overflow-y: auto;
    }
  }
}
</style>
